
local TankManager = import(".TankManager")

local GameManager = class("GameManager", require("unity.LuaMonoBehaviour"))

---
---m_NumRoundsToWin number
---m_StartDelay number
---m_EndDelay number
---m_CameraControl LuaMonoBehaviour
---m_MessageText Text
---m_TankPrefab GameObject
---m_Tanks [TankManager]
---
function GameManager:Awake()
    self.m_RoundNumber = 0
    self.m_RoundWinner = nil
    self.m_GameWinner = nil
end

function GameManager:Start()
    self:SpawnAllTanks()
    self:SetCameraTargets()
    coroutine.start(function()
        self:GameLoop()
    end)
end

function GameManager:SpawnAllTanks()
    for i,v in ipairs(self.m_Tanks) do
        local tank = TankManager.New(v)
        tank.m_Instance = UnityEngine.Object.Instantiate(self.m_TankPrefab, v.m_SpawnPoint.position, v.m_SpawnPoint.rotation)
        tank.m_PlayerNumber = i
        tank:Setup()
        self.m_Tanks[i] = tank
    end
end

function GameManager:SetCameraTargets()
    local targets = {}
    for i,t in ipairs(self.m_Tanks) do
        targets[#targets + 1] = t.m_Instance.transform
    end
    self.m_CameraControl:SetTargets(targets)
end

function GameManager:GameLoop()
    self:RoundStarting()
    self:RoundPlaying()
    self:RoundEnding()
    if self.m_GameWinner then
        UnityEngine.SceneManagement.SceneManager.LoadScene(0)
    else
        coroutine.start(function()
            self:GameLoop()
        end)
    end
end

function GameManager:RoundStarting()
    self:ResetAllTanks ()
    self:DisableTankControl ()
    self.m_CameraControl:SetStartPositionAndSize()
    self.m_RoundNumber = self.m_RoundNumber + 1
    self.m_MessageText.text = "ROUND " .. tostring(self.m_RoundNumber) 
    coroutine.sleep(self.m_StartDelay)
end

function GameManager:RoundPlaying()
    self:EnableTankControl ()
    self.m_MessageText.text = ""
    coroutine.waituntil(function() return self:OneTankLeft() end) 
end

function GameManager:RoundEnding()
    self:DisableTankControl ()
    self.m_RoundWinner = nil
    self.m_RoundWinner = self:GetRoundWinner ()
    if self.m_RoundWinner then
        self.m_RoundWinner.m_Wins = self.m_RoundWinner.m_Wins + 1
    end
    self.m_GameWinner = self:GetGameWinner ()
    local message = self:EndMessage ()
    self.m_MessageText.text = message
    coroutine.sleep(self.m_EndDelay)
end

function GameManager:OneTankLeft()
    local numTanksLeft = 0
    for i,t in ipairs(self.m_Tanks) do
        if t.m_Instance.activeSelf then
            numTanksLeft = numTanksLeft + 1
        end
    end
    return numTanksLeft <= 1
end

function GameManager:GetRoundWinner()
    for i,t in ipairs(self.m_Tanks) do
        if t.m_Instance.activeSelf then
            return t
        end
    end
end

function GameManager:GetGameWinner()
    for i,t in ipairs(self.m_Tanks) do
        if t.m_Wins == self.m_NumRoundsToWin then
            return t
        end
    end
end

function GameManager:EndMessage()
    local message = "DRAW!"
    if self.m_RoundWinner then
        message = self.m_RoundWinner.m_ColoredPlayerText .. " WINS THE ROUND!"
    end
    message = message .. "\n\n\n\n"
    for i,t in ipairs(self.m_Tanks) do
        message = message .. t.m_ColoredPlayerText .. ": " .. tostring(t.m_Wins) .. " WINS\n"
    end
    if self.m_GameWinner then
        message = self.m_GameWinner.m_ColoredPlayerText .. " WINS THE GAME!"
    end
    
    return message;
end

function GameManager:ResetAllTanks()
    for i,t in ipairs(self.m_Tanks) do
        t:Reset()
    end
end

function GameManager:EnableTankControl()
    for i,t in ipairs(self.m_Tanks) do
        t:EnableControl()
    end
end

function GameManager:DisableTankControl()
    for i,t in ipairs(self.m_Tanks) do
        t:DisableControl()
    end
end

return GameManager
